package 小测试;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Administrator on 2017/8/6.
 */
//在正则表达式中有特殊意义的字符，都需要用双斜杠保护起来
    //显示的单斜杠，在正则表达式中要用"\\\\"来匹配。(显示的单斜杠=java的"\\"=regex的"\\\\")
public class 正则表达式 {
    public static void main(String[] args) {
        String s="1+2=?3*4{5}&6";
        String[] strs=s.split("\\&");
//        System.out.println(Arrays.toString(strs));
        正则表达式的特殊构造_非捕获();
    }

//    特殊构造（非捕获）---仅匹配给定格式的字符，比如子字符串以或者不以什么开头或结尾。括号里面表示预测的子字符串格式。
//            (?:X)     X，作为非捕获组
//            (?idmsux-idmsux)     Nothing，但是将匹配标志idmsux on -> off
//            (?idmsux-idmsux:X)   X，作为带有给定标志 i d m s u x on -> off
//            (?=X)     X，通过零宽度的正 lookahead   (X,via zero-width positive lookahead)
//            (?!X)     X，通过零宽度的负 lookahead   (X,via zero-width negative lookahead)
//            (?<=X)     X，通过零宽度的正 lookbehind (X,via zero-width positive lookbehind)
//            (?(?>X)     X，作为独立的非捕获组

//    lookahead和lookbehind也就是先行和后行。
//       先行指的是，在进行断言的时候，字符串匹配引擎指针会被向前(右边)移动以进行断言（由于zero-width，所以之后会再被移回）。
//       后行指的是，在进行断言的时候，字符串匹配引擎指针会被向后(左边)移动以进行断言（由于zero-width，所以之后会再被移回）。
//    zero-width也就是零宽度。指的是断言前后不会改变当前字符串匹配引擎的指针位置。
//    positive和negative: 表示是预测匹配还是不匹配(即后面是否是这样的字符)。
//    1、(?=X)，预测其前边字串匹配位置后为X。
//       (?=X)的意思就是预测匹配位置之后出现的应该是X。如果符合则匹配上。
//       在(?=X)后边带上不以X为开始的任意字符串都将导致该表达式不能被匹配。因为预测不改变当前字符串搜索的指针（零宽度）
//    例子：表达式"a(?=b)c"不能匹配"abc"，也不能匹配"ac"、"ab"。而且不能匹配任何字符串。
//          因为其预测匹配a的位置后，应该是b，但是，又要求a之后是c(即预测和给定的不一致)。

    private static void 正则表达式的特殊构造_非捕获() {
        //1、编译正则表达式到模式中
//        String regex="a(?=b)c"; //预测与给定矛盾的正则表达式，即不能匹配任何字符
//        String regex="a(?=b)b"; //向右匹配ab组合  (结果：ab, start=4, end=6；ab, start=7, end=9)
//        String regex="a(?!b)"; //向右匹配a字符后面不是b字符的 那个a字符  (结果：a, start=0, end=1)
//        String regex="b(?<=b)"; //向左匹配,匹配位置左边字符串 以b结尾  (结果：b, start=5, end=6；b, start=8, end=9)
//        String regex="5(?<!b)"; //向左匹配,匹配位置左边字符串 不以b结尾  (结果：5, start=3, end=4)
        String regex=".*?(?=\\()";  //非贪婪匹配+非捕获

        Pattern pattern = Pattern.compile(regex);
        //2、通过模式对象加载被匹配者
        Matcher m = pattern.matcher("北京市(海淀区)(朝阳区)");
        System.out.println("被匹配字符串：a125ab*ab北京市(海淀区)(朝阳区)");
        //3、查找并返回匹配结果
//        find()对字符串进行匹配,匹配到的字符串可以在任何位置.
//        start()返回匹配到的子字符串在字符串中的索引位置.
//        end()返回匹配中的最后一个字符 之后的偏移量(相对数组最前端).
//        group()返回匹配到的子字符串
        while(m.find()) {
            System.out.println(m.group()+", start="+m.start()+", end="+m.end());
        }
    }
}
